import { HttpException, Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { getPagination, listToTree, mapToObj } from 'src/utils';
import { ILike, Repository } from 'typeorm';
import { EditPermissionDto, ListDTO } from './dto/permission.dto';
import { PermissionEntity } from './entity/permission.entity';

@Injectable()
export class PermissionService {
  constructor(
    @InjectRepository(PermissionEntity)
    private readonly permissionRepository: Repository<PermissionEntity>,
  ) {}

  // 新建菜单
  async create(post: Partial<PermissionEntity>): Promise<PermissionEntity> {
    const { name, url } = post;
    if (!name) {
      throw new HttpException('菜单名称不能为空', 401);
    }
    if (!url) {
      throw new HttpException('菜单路径不能为空', 401);
    }
    const doc = await this.permissionRepository.findOne({ where: { url } });
    if (doc) {
      throw new HttpException('菜单路径已存在', 401);
    }
    return await this.permissionRepository.save(post);
  }

  // 获取菜单列表
  async findAll(query: ListDTO): Promise<any> {
    const { page = 1, pageSize = 10, name } = query;
    // 自定义查询条件
    const queryMap = new Map();
    queryMap.set('del_flag', 0);
    queryMap.set('parent_id', '');
    if (name) {
      queryMap.set('role_name', ILike(name));
    }

    const getList = this.permissionRepository
      .createQueryBuilder('sys_permission')
      .where(mapToObj(queryMap))
      .select([
        'sys_permission.id',
        'sys_permission.name',
        'sys_permission.url',
        'sys_permission.component',
        'sys_permission.component_name',
        'sys_permission.menu_type',
        'sys_permission.perms',
        'sys_permission.perms_type',
        'sys_permission.sort',
        'sys_permission.icon',
        'sys_permission.is_route',
        'sys_permission.is_leaf',
        'sys_permission.keep',
        'sys_permission.hidden',
        'sys_permission.status',
        'sys_permission.description',
      ])
      .skip((page - 1) * pageSize)
      .take(pageSize)
      .printSql()
      .getManyAndCount();

    // 查询子集数据
    const sql = `SELECT id,name,url,parent_id,component,component_name,
    menu_type,perms,perms_type,sort,icon,is_route,is_leaf,keep,hidden,
    status,description FROM sys_permission WHERE del_flag=0 AND parent_id !=''`;
    const subset = await this.permissionRepository.query(sql);
    // 以父级条数进行分页
    const [list, total] = await getList;
    const pagination = getPagination(total, pageSize, page);

    // 拼装父子级别数据
    const reslut = listToTree([...list, ...subset]);
    const result = {
      reslut,
      pagination,
    };
    return result;
  }

  // 获取菜单权限树
  async getPermissionTree() {
    const sql = `SELECT id,name,url,parent_id,component,component_name,
    menu_type,perms,perms_type,sort,icon,is_route,is_leaf,keep,hidden,
    status,description FROM sys_permission WHERE del_flag=0 ORDER BY sort ASC`;
    const sql_result = await this.permissionRepository.query(sql);
    // list to tree
    const reslut = listToTree(sql_result);
    return { reslut: reslut };
  }

  // 根据登录用户id（用户-角色-权限-连表查询-当前用户拥有多少权限菜单）
  async getUserPermission(query) {
    const { id } = query;
    const sql = `SELECT p.id,p.name,p.parent_id,p.url,p.component,p.component_name,p.menu_type,p.perms,
    p.perms_type,p.sort,p.icon,p.is_route,p.is_leaf,p.keep,p.hidden,p.status,p.description 
    FROM sys_user AS u 
    LEFT JOIN sys_user_role AS ur ON u.id = ur.user_id 
    LEFT JOIN sys_roles AS r ON r.id = ur.role_id 
    LEFT JOIN sys_role_permission AS rp ON rp.role_id = r.id 
    LEFT JOIN sys_permission AS p ON p.id = rp.permission_id 
    WHERE u.id='${id}' AND p.del_flag=0`;
    const sql_result = await this.permissionRepository.query(sql);
    // list to tree
    const reslut = listToTree(sql_result);
    return { reslut: reslut };
  }

  // 通过id获取指定菜单信息
  async findById(query) {
    const { id } = query;
    const sql = `SELECT id,name,url,parent_id,component,component_name,
    menu_type,perms,perms_type,sort,icon,is_route,is_leaf,keep,hidden,
    status,description FROM sys_permission WHERE id ='${id}' AND del_flag=0`;
    const roleDetial = await this.permissionRepository.query(sql);
    if (roleDetial.length == 0) {
      throw new NotFoundException('找不到对应id数据');
    }
    const result = {
      result: roleDetial[0],
    };
    return result;
  }

  // 更新菜单
  async updateById(id: string, body: EditPermissionDto) {
    const reslut = await this.permissionRepository.update(id, body);
    return reslut;
  }

  // 删除菜单
  async remove(query) {
    const { id } = query;
    const sql = `SELECT id FROM sys_permission WHERE id ='${id}' AND del_flag=0`;
    const existRole = await this.permissionRepository.query(sql);
    if (existRole.length == 0) {
      throw new HttpException(`id为${id}的菜单不存在`, 401);
    }
    const update_sql = `UPDATE sys_permission SET del_flag=1 WHERE id='${id}'`;
    const result = await this.permissionRepository.query(update_sql);
    if (result) {
      return '删除成功！';
    } else {
      return '删除失败！';
    }
  }
}
